home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-10 | 12.9 KB | 488 lines | [TEXT/PJMM] |
- unit WEScraps;
-
- { WASTE PROJECT: }
- { Routines for manipulating style scraps and object soups }
-
- { Copyright © 1993-1994 Marco Piovanelli }
- { All Rights Reserved }
-
- interface
- uses
- WEDrawing;
-
- function _WEPrependStyle (hStyleScrap: Handle;
- var info: WERunInfo;
- offsetDelta: LongInt): OSErr;
- function _WEAppendStyle (hStyleScrap: Handle;
- var info: WERunInfo;
- offset: LongInt): OSErr;
- function _WEPrependObject (hSoup: Handle;
- var info: WERunInfo;
- offsetDelta: LongInt): OSErr;
- function _WEAppendObject (hSoup: Handle;
- var info: WERunInfo;
- offset: LongInt): OSErr;
- function WECopyRange (rangeStart, rangeEnd: LongInt;
- hText, hStyles, hSoup: Handle;
- hWE: WEHandle): OSErr;
- function WECopy (hWE: WEHandle): OSErr;
-
- implementation
- uses
- AppleEvents;
-
- function _WEPrependStyle (hStyleScrap: Handle;
- var info: WERunInfo;
- offsetDelta: LongInt): OSErr;
-
- { compare the stylistic attributes in info with the first element of the specified }
- { style scrap: if they differ, prepend a new element to the style scrap. }
- { in any case, advance all character offsets in the style scrap by offsetDelta }
-
- label
- 1;
- var
- pScrap: TEStyleScrapPtr;
- scrapSize: Size;
- i: Integer;
- err: OSErr;
- begin
- pScrap := TEStyleScrapHandle(hStyleScrap)^;
- if (_WEBlockCmp(@pScrap^.scrpStyleTab[0].scrpTEAttrs, @info.runAttrs.runTEAttrs, SizeOf(info.runAttrs.runTEAttrs)) = false) then
- begin
-
- { lengthen the style scrap }
- scrapSize := %_GetHandleSize(hStyleScrap);
- err := %_SetHandleSize(hStyleScrap, scrapSize + SizeOf(TEStyleScrapElement));
- if (err <> noErr) then
- goto 1;
-
- { move old contents forward }
- pScrap := TEStyleScrapHandle(hStyleScrap)^;
- %_BlockMoveData(@pScrap^.scrpStyleTab[0], @pScrap^.scrpStyleTab[1], scrapSize - SizeOf(pScrap^.scrpNStyles));
-
- { insert a new element at the beginning }
- pScrap^.scrpStyleTab[0].scrpStartChar := 0;
- pScrap^.scrpStyleTab[0].scrpTEAttrs := info.runAttrs.runTEAttrs;
-
- { increment scrap counter }
- pScrap^.scrpNStyles := pScrap^.scrpNStyles + 1;
-
- end; { if not _WEBlockCmp }
-
- { update char offsets within the style scrap }
- for i := pScrap^.scrpNStyles - 1 downto 1 do
- with pScrap^.scrpStyleTab[i] do
- scrpStartChar := scrpStartChar + offsetDelta;
-
- { clear result code }
- err := noErr;
-
- 1:
- { return result code }
- _WEPrependStyle := err;
-
- end; { _WEPrependStyle }
-
- function _WEAppendStyle (hStyleScrap: Handle;
- var info: WERunInfo;
- offset: LongInt): OSErr;
-
- { compare the stylistic attributes in info with the last element of the specified }
- { style scrap: if they differ, append a new element to the style scrap. }
-
- label
- 1;
- var
- pScrap: TEStyleScrapPtr;
- element: TEStyleScrapElement;
- err: OSErr;
- begin
- pScrap := TEStyleScrapHandle(hStyleScrap)^;
- if (_WEBlockCmp(@pScrap^.scrpStyleTab[pScrap^.scrpNStyles - 1].scrpTEAttrs, @info.runAttrs.runTEAttrs, SizeOf(info.runAttrs.runTEAttrs)) = false) then
- begin
-
- { create a new style scrap element }
- element.scrpStartChar := offset;
- element.scrpTEAttrs := info.runAttrs.runTEAttrs;
-
- { append it at the end of the style scrap }
- err := %_PtrAndHand(@element, hStyleScrap, SizeOf(element));
- if (err <> noErr) then
- goto 1;
-
- { increment scrap counter }
- pScrap := TEStyleScrapHandle(hStyleScrap)^;
- pScrap^.scrpNStyles := pScrap^.scrpNStyles + 1;
-
- end; { if not _WEBlockCmp }
-
- { clear result code }
- err := noErr;
-
- 1:
- { return result code }
- _WEAppendStyle := err;
-
- end; { _WEAppendStyle }
-
- function _WEPrependObject (hSoup: Handle;
- var info: WERunInfo;
- offsetDelta: LongInt): OSErr;
-
- { if info describes an embedded object, prepend a new object descriptor, }
- { complete with the associated object data, to the specified soup. }
- { in any case, advance all character offsets in the soup by offsetDelta }
-
- label
- 1;
- var
- pDesc: WEObjectDescPtr;
- pSoup: WESoupPtr;
- soupSize, objectDataSize, extraSize: Size;
- i: Integer;
- err: OSErr;
- begin
-
- { get size of existing soup }
- soupSize := %_GetHandleSize(hSoup);
-
- { extract object descriptor handle from WERunInfo record }
- { if hObject is non-NIL, info describes an embedded object }
- if (info.runAttrs.runStyle.tsObject <> kNullObject) then
- begin
- pDesc := WEObjectDescHandle(info.runAttrs.runStyle.tsObject)^;
-
- { get size of object data }
- objectDataSize := %_GetHandleSize(pDesc^.objectDataHandle);
-
- { extra size to add to existing soup is descriptor size + object data size }
- extraSize := SizeOf(WESoup) + objectDataSize;
-
- { resize the soup }
- err := %_SetHandleSize(hSoup, soupSize + extraSize);
- if (err <> noErr) then
- goto 1;
-
- { move old contents forward }
- pSoup := WESoupHandle(hSoup)^;
- %_BlockMoveData(Ptr(pSoup), Ptr(LongInt(pSoup) + extraSize), soupSize);
-
- { insert the new object descriptor at the beginning }
- _WEBlockClr(Ptr(pSoup), SizeOf(WESoup));
- pDesc := WEObjectDescHandle(info.runAttrs.runStyle.tsObject)^;
- pSoup^.soupType := pDesc^.objectType;
- pSoup^.soupSize := pDesc^.objectSize;
- pSoup^.soupDataSize := objectDataSize;
-
- { then copy the object data }
- %_BlockMoveData(pDesc^.objectDataHandle^, Ptr(LongInt(pSoup) + SizeOf(WESoup)), objectDataSize);
-
- end
- else
- begin
- pSoup := WESoupHandle(hSoup)^;
- extraSize := 0;
- end;
-
- { update char offsets within the soup }
- while (soupSize > 0) do
- begin
- pSoup := WESoupPtr(LongInt(pSoup) + extraSize);
- pSoup^.soupOffset := pSoup^.soupOffset + offsetDelta;
- extraSize := pSoup^.soupDataSize + SizeOf(WESoup);
- soupSize := soupSize - extraSize;
- end;
-
- { clear result code }
- err := noErr;
-
- 1:
- { return result code }
- _WEPrependObject := err;
-
- end; { _WEPrependObject }
-
- function _WEAppendObject (hSoup: Handle;
- var info: WERunInfo;
- offset: LongInt): OSErr;
-
- { if info describes an embedded object, append a new object descriptor, }
- { complete with the associated object data, to the specified soup. }
-
- label
- 1;
- var
- pDesc: WEObjectDescPtr;
- hObjectData: Handle;
- soupItem: WESoup;
- saveDataLock: Boolean;
- err: OSErr;
- begin
- if (info.runAttrs.runStyle.tsObject <> kNullObject) then
- begin
- pDesc := WEObjectDescHandle(info.runAttrs.runStyle.tsObject)^;
- hObjectData := pDesc^.objectDataHandle;
-
- { fill in a soup item }
- _WEBlockClr(@soupItem, SizeOf(soupItem));
- soupItem.soupOffset := offset;
- soupItem.soupType := pDesc^.objectType;
- soupItem.soupSize := pDesc^.objectSize;
- soupItem.soupDataSize := %_GetHandleSize(hObjectData);
-
- { append it to the soup handle }
- err := %_PtrAndHand(@soupItem, hSoup, SizeOf(soupItem));
- if (err <> noErr) then
- goto 1;
-
- { append the actual object data to the soup handle }
- saveDataLock := _WESetHandleLock(hObjectData, true);
- err := %_PtrAndHand(hObjectData^, hSoup, soupItem.soupDataSize);
- IgnoreBoolean(_WESetHandleLock(hObjectData, saveDataLock));
- if (err <> noErr) then
- goto 1;
-
- end; { if object reference is not NIL }
-
- { clear result code }
- err := noErr;
-
- 1:
- { return result code }
- _WEAppendObject := err;
-
- end; { _WEAppendObject }
-
- function WECopyRange (rangeStart, rangeEnd: LongInt;
- hText, hStyles, hSoup: Handle;
- hWE: WEHandle): OSErr;
-
- { Make a copy of the specified range of text: store the characters in hText }
- { and the associated style scrap in hStyles. The handles are resized as necessary. }
- { Specify NIL in hText or hStyles if you don't want the corresponding info returned. }
-
- label
- 1;
- var
- pWE: WEPtr;
- rangeLength: LongInt;
- firstRun, nRuns, i: LongInt;
- startChar: LongInt;
- info: WERunInfo;
- pElement: Ptr;
- pDesc: WEObjectDescPtr;
- saveWELock: Boolean;
- err: OSErr;
- begin
-
- { lock the WE record }
- saveWELock := _WESetHandleLock(hWE, true);
- pWE := hWE^;
-
- { range-check parameters and reorder them if necessary }
- rangeStart := _WEPinInRange(rangeStart, 0, pWE^.textLength);
- rangeEnd := _WEPinInRange(rangeEnd, 0, pWE^.textLength);
- _WEReorder(rangeStart, rangeEnd);
- rangeLength := rangeEnd - rangeStart;
-
- if (hText <> nil) then
- begin
-
- { resize the given handle }
- err := %_SetHandleSize(hText, rangeLength);
- if (err <> noErr) then
- goto 1;
-
- { copy the text range }
- %_BlockMoveData(Ptr(LongInt(pWE^.hText^) + rangeStart), hText^, rangeLength);
-
- end; { if (hText <> NIL) }
-
- { make the soup handle zero-length }
- if (hSoup <> nil) then
- begin
- err := %_SetHandleSize(hSoup, 0);
- if (err <> noErr) then
- goto 1;
- end;
-
- if (hStyles <> nil) or (hSoup <> nil) then
- begin
-
- { count how many style runs there are in the selection range }
- firstRun := _WEOffsetToRun(rangeStart, hWE);
- nRuns := _WEOffsetToRun(rangeEnd - 1, hWE) - firstRun + 1;
-
- if (hStyles <> nil) then
- begin
-
- { resize the given style scrap handle and lock it in high heap }
- err := %_SetHandleSize(hStyles, %_LongMul(0, nRuns, SizeOf(ScrpSTElement)) + 2);
- if (err <> noErr) then
- goto 1;
- HLockHi(hStyles);
- pElement := hStyles^;
-
- { fill in the style count in the style scrap }
- { *** POTENTIAL PROBLEM: if nRuns > 32767, scrpNStyles will be invalid *** }
- IntegerPtr(pElement)^ := nRuns;
- pElement := Ptr(LongInt(pElement) + SizeOf(Integer));
-
- end; { if hStyles <> NIL }
-
- { loop through every style run in the selection range }
- for i := 0 to nRuns - 1 do
- begin
- _WEGetIndStyle(firstRun + i, info, hWE);
-
- { calculate the start character for this style run, relative to the beginning of the range }
- startChar := info.runStart - rangeStart;
- if (startChar < 0) then
- begin
- startChar := 0;
- info.runAttrs.runStyle.tsObject := kNullObject;
- end;
-
- { fill in an item in the style scrap }
- if (hStyles <> nil) then
- begin
- info.runAttrs.runStyle.tsFlags := 0; { don't export internal flags }
- TEStyleScrapElementPtr(pElement)^.scrpStartChar := startChar;
- TEStyleScrapElementPtr(pElement)^.scrpTEAttrs := info.runAttrs.runTEAttrs;
- pElement := Ptr(LongInt(pElement) + SizeOf(TEStyleScrapElement));
- end;
-
- if (hSoup <> nil) then
- begin
-
- { if this style run references an embedded object, append it to the "soup" }
- err := _WEAppendObject(hSoup, info, startChar);
- if (err <> noErr) then
- goto 1;
- end;
-
- end; { for }
- end;
-
- { clear result code }
- err := noErr;
-
- 1:
- { return result code }
- WECopyRange := err;
-
- { unlock the style scrap handle }
- if (hStyles <> nil) then
- HUnlock(hStyles);
-
- { unlock the WE record }
- IgnoreBoolean(_WESetHandleLock(hWE, saveWELock));
-
- end; { WECopyRange }
-
- function WECopy (hWE: WEHandle): OSErr;
-
- { Copy the selection range to the desk scrap }
-
- label
- 0, 1;
- type
- AEDescPtr = ^AEDesc;
- AEDescHandle = ^AEDescPtr;
- var
- pWE: WEPtr;
- d: array[0..2] of AEDesc;
- hObjectDesc: WEObjectDescHandle;
- i, numTypes: Integer;
- hItem: Handle;
- itemSize: Size;
- disposeData: Boolean;
- saveDataLock, saveWELock: Boolean;
- err: OSErr;
- begin
- d[0].dataHandle := nil;
- d[1].dataHandle := nil;
- d[2].dataHandle := nil;
- disposeData := false;
-
- { lock the WE record }
- saveWELock := _WESetHandleLock(hWE, true);
- pWE := hWE^;
-
- { do nothing if the selection range is empty }
- if (pWE^.selStart = pWE^.selEnd) then
- goto 0;
-
- { clear the desk scrap }
- err := ZeroScrap;
- if (err <> noErr) then
- goto 1;
-
- { if the selection range consists of an embedded object, copy that }
- if (WEGetSelectedObject(hObjectDesc, hWE) = noErr) then
- begin
- d[0] := AEDescHandle(hObjectDesc)^^;
- numTypes := 1;
- end
- else
- begin
-
- { allocate three zero-length handles to hold the text, the styles and the "soup" }
- for i := 0 to 2 do
- begin
- err := _WEAllocate(0, kAllocTemp, d[i].dataHandle);
- if (err <> noErr) then
- goto 1;
- end; { for }
-
- { make a copy of the selection text, styles and soup }
- err := WECopyRange(pWE^.selStart, pWE^.selEnd, d[0].dataHandle, d[1].dataHandle, d[2].dataHandle, hWE);
- if (err <> noErr) then
- goto 1;
-
- { tag the data }
- d[0].descriptorType := kTypeText;
- d[1].descriptorType := kTypeStyles;
- d[2].descriptorType := kTypeSoup;
- numTypes := 3;
- disposeData := true;
- end;
-
- { copy the items to the desk scrap }
- for i := 0 to numTypes - 1 do
- begin
- hItem := d[i].dataHandle;
- itemSize := %_GetHandleSize(hItem);
- if (itemSize > 0) then
- begin
- saveDataLock := _WESetHandleLock(hItem, true);
- err := PutScrap(itemSize, d[i].descriptorType, hItem^);
- IgnoreBoolean(_WESetHandleLock(hItem, saveDataLock));
- if (err <> noErr) then
- goto 1;
- end;
- end; { for }
-
- 0:
- { clear result code }
- err := noErr;
-
- 1:
- { return result code }
- WECopy := err;
-
- { clean up }
- if (disposeData) then
- begin
- _WEForgetHandle(d[0].dataHandle);
- _WEForgetHandle(d[1].dataHandle);
- _WEForgetHandle(d[2].dataHandle);
- end;
-
- { unlock the WE record }
- IgnoreBoolean(_WESetHandleLock(hWE, saveWELock));
-
- end; { WECopy }
-
- end.